home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / platform.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  30KB  |  1,081 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. ''' This module tries to retrieve as much platform-identifying data as
  5.     possible. It makes this information available via function APIs.
  6.  
  7.     If called from the command line, it prints the platform
  8.     information concatenated as single string to stdout. The output
  9.     format is useable as part of a filename.
  10.  
  11. '''
  12. __copyright__ = '\n    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com\n    Copyright (c) 2000-2003, eGenix.com Software GmbH; mailto:info@egenix.com\n\n    Permission to use, copy, modify, and distribute this software and its\n    documentation for any purpose and without fee or royalty is hereby granted,\n    provided that the above copyright notice appear in all copies and that\n    both that copyright notice and this permission notice appear in\n    supporting documentation or portions thereof, including modifications,\n    that you make.\n\n    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO\n    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,\n    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING\n    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,\n    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION\n    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !\n\n'
  13. __version__ = '1.0.2'
  14. import sys
  15. import string
  16. import os
  17. import re
  18. _libc_search = re.compile('(__libc_init)|(GLIBC_([0-9.]+))|(libc(_\\w+)?\\.so(?:\\.(\\d[0-9.]*))?)')
  19.  
  20. def libc_ver(executable = sys.executable, lib = '', version = '', chunksize = 2048):
  21.     ''' Tries to determine the libc version that the file executable
  22.         (which defaults to the Python interpreter) is linked against.
  23.  
  24.         Returns a tuple of strings (lib,version) which default to the
  25.         given parameters in case the lookup fails.
  26.  
  27.         Note that the function has intimate knowledge of how different
  28.         libc versions add symbols to the executable and thus is probably
  29.         only useable for executables compiled using gcc.
  30.  
  31.         The file is read and scanned in chunks of chunksize bytes.
  32.  
  33.     '''
  34.     f = open(executable, 'rb')
  35.     binary = f.read(chunksize)
  36.     pos = 0
  37.     while None:
  38.         m = _libc_search.search(binary, pos)
  39.         if not m:
  40.             binary = f.read(chunksize)
  41.             if not binary:
  42.                 break
  43.             
  44.             pos = 0
  45.             continue
  46.         
  47.         (libcinit, glibc, glibcversion, so, threads, soversion) = m.groups()
  48.         if libcinit and not lib:
  49.             lib = 'libc'
  50.         elif glibc:
  51.             if lib != 'glibc':
  52.                 lib = 'glibc'
  53.                 version = glibcversion
  54.             elif glibcversion > version:
  55.                 version = glibcversion
  56.             
  57.         elif so:
  58.             if lib != 'glibc':
  59.                 lib = 'libc'
  60.                 if soversion > version:
  61.                     version = soversion
  62.                 
  63.                 if threads and version[-len(threads):] != threads:
  64.                     version = version + threads
  65.                 
  66.             
  67.         
  68.         pos = m.end()
  69.     f.close()
  70.     return (lib, version)
  71.  
  72.  
  73. def _dist_try_harder(distname, version, id):
  74.     ''' Tries some special tricks to get the distribution
  75.         information in case the default method fails.
  76.  
  77.         Currently supports older SuSE Linux, Caldera OpenLinux and
  78.         Slackware Linux distributions.
  79.  
  80.     '''
  81.     if os.path.exists('/var/adm/inst-log/info'):
  82.         info = open('/var/adm/inst-log/info').readlines()
  83.         distname = 'SuSE'
  84.         for line in info:
  85.             tv = string.split(line)
  86.             if len(tv) == 2:
  87.                 (tag, value) = tv
  88.             
  89.             if tag == 'MIN_DIST_VERSION':
  90.                 version = string.strip(value)
  91.                 continue
  92.             len(tv) == 2
  93.             if tag == 'DIST_IDENT':
  94.                 values = string.split(value, '-')
  95.                 id = values[2]
  96.                 continue
  97.         
  98.         return (distname, version, id)
  99.     
  100.     if os.path.exists('/etc/.installed'):
  101.         info = open('/etc/.installed').readlines()
  102.         for line in info:
  103.             pkg = string.split(line, '-')
  104.             if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
  105.                 return ('OpenLinux', pkg[1], id)
  106.                 continue
  107.         
  108.     
  109.     if os.path.isdir('/usr/lib/setup'):
  110.         verfiles = os.listdir('/usr/lib/setup')
  111.         for n in range(len(verfiles) - 1, -1, -1):
  112.             if verfiles[n][:14] != 'slack-version-':
  113.                 del verfiles[n]
  114.                 continue
  115.         
  116.         if verfiles:
  117.             verfiles.sort()
  118.             distname = 'slackware'
  119.             version = verfiles[-1][14:]
  120.             return (distname, version, id)
  121.         
  122.     
  123.     return (distname, version, id)
  124.  
  125. _release_filename = re.compile('(\\w+)[-_](release|version)')
  126. _release_version = re.compile('([\\d.]+)[^(]*(?:\\((.+)\\))?')
  127.  
  128. def dist(distname = '', version = '', id = '', supported_dists = ('SuSE', 'debian', 'redhat', 'mandrake')):
  129.     ''' Tries to determine the name of the Linux OS distribution name.
  130.  
  131.         The function first looks for a distribution release file in
  132.         /etc and then reverts to _dist_try_harder() in case no
  133.         suitable files are found.
  134.  
  135.         Returns a tuple (distname,version,id) which default to the
  136.         args given as parameters.
  137.  
  138.     '''
  139.     
  140.     try:
  141.         etc = os.listdir('/etc')
  142.     except os.error:
  143.         return (distname, version, id)
  144.  
  145.     for file in etc:
  146.         m = _release_filename.match(file)
  147.         if m:
  148.             (_distname, dummy) = m.groups()
  149.             if _distname in supported_dists:
  150.                 distname = _distname
  151.                 break
  152.             
  153.         _distname in supported_dists
  154.     else:
  155.         return _dist_try_harder(distname, version, id)
  156.     f = open('/etc/' + file, 'r')
  157.     firstline = f.readline()
  158.     f.close()
  159.     m = _release_version.search(firstline)
  160.     if m:
  161.         (_version, _id) = m.groups()
  162.         if _version:
  163.             version = _version
  164.         
  165.         if _id:
  166.             id = _id
  167.         
  168.     else:
  169.         l = string.split(string.strip(firstline))
  170.         if l:
  171.             version = l[0]
  172.             if len(l) > 1:
  173.                 id = l[1]
  174.             
  175.         
  176.     return (distname, version, id)
  177.  
  178.  
  179. class _popen:
  180.     """ Fairly portable (alternative) popen implementation.
  181.  
  182.         This is mostly needed in case os.popen() is not available, or
  183.         doesn't work as advertised, e.g. in Win9X GUI programs like
  184.         PythonWin or IDLE.
  185.  
  186.         Writing to the pipe is currently not supported.
  187.  
  188.     """
  189.     tmpfile = ''
  190.     pipe = None
  191.     bufsize = None
  192.     mode = 'r'
  193.     
  194.     def __init__(self, cmd, mode = 'r', bufsize = None):
  195.         if mode != 'r':
  196.             raise ValueError, 'popen()-emulation only supports read mode'
  197.         
  198.         import tempfile as tempfile
  199.         self.tmpfile = tmpfile = tempfile.mktemp()
  200.         os.system(cmd + ' > %s' % tmpfile)
  201.         self.pipe = open(tmpfile, 'rb')
  202.         self.bufsize = bufsize
  203.         self.mode = mode
  204.  
  205.     
  206.     def read(self):
  207.         return self.pipe.read()
  208.  
  209.     
  210.     def readlines(self):
  211.         if self.bufsize is not None:
  212.             return self.pipe.readlines()
  213.         
  214.  
  215.     
  216.     def close(self, remove = os.unlink, error = os.error):
  217.         if self.pipe:
  218.             rc = self.pipe.close()
  219.         else:
  220.             rc = 255
  221.         if self.tmpfile:
  222.             
  223.             try:
  224.                 remove(self.tmpfile)
  225.             except error:
  226.                 pass
  227.             except:
  228.                 None<EXCEPTION MATCH>error
  229.             
  230.  
  231.         None<EXCEPTION MATCH>error
  232.         return rc
  233.  
  234.     __del__ = close
  235.  
  236.  
  237. def popen(cmd, mode = 'r', bufsize = None):
  238.     ''' Portable popen() interface.
  239.     '''
  240.     popen = None
  241.     if os.environ.get('OS', '') == 'Windows_NT':
  242.         
  243.         try:
  244.             import win32pipe as win32pipe
  245.         except ImportError:
  246.             pass
  247.  
  248.         popen = win32pipe.popen
  249.     
  250.     if popen is None:
  251.         if hasattr(os, 'popen'):
  252.             popen = os.popen
  253.             if sys.platform == 'win32':
  254.                 
  255.                 try:
  256.                     popen('')
  257.                 except os.error:
  258.                     popen = _popen
  259.                 except:
  260.                     None<EXCEPTION MATCH>os.error
  261.                 
  262.  
  263.             None<EXCEPTION MATCH>os.error
  264.         else:
  265.             popen = _popen
  266.     
  267.     if bufsize is None:
  268.         return popen(cmd, mode)
  269.     else:
  270.         return popen(cmd, mode, bufsize)
  271.  
  272.  
  273. def _norm_version(version, build = ''):
  274.     ''' Normalize the version and build strings and return a single
  275.         vesion string using the format major.minor.build (or patchlevel).
  276.     '''
  277.     l = string.split(version, '.')
  278.     if build:
  279.         l.append(build)
  280.     
  281.     
  282.     try:
  283.         ints = map(int, l)
  284.     except ValueError:
  285.         strings = l
  286.  
  287.     strings = map(str, ints)
  288.     version = string.join(strings[:3], '.')
  289.     return version
  290.  
  291. _ver_output = re.compile('(?:([\\w ]+) ([\\w.]+) .*Version ([\\d.]+))')
  292.  
  293. def _syscmd_ver(system = '', release = '', version = '', supported_platforms = ('win32', 'win16', 'dos', 'os2')):
  294.     ''' Tries to figure out the OS version used and returns
  295.         a tuple (system,release,version).
  296.  
  297.         It uses the "ver" shell command for this which is known
  298.         to exists on Windows, DOS and OS/2. XXX Others too ?
  299.  
  300.         In case this fails, the given parameters are used as
  301.         defaults.
  302.  
  303.     '''
  304.     if sys.platform not in supported_platforms:
  305.         return (system, release, version)
  306.     
  307.     for cmd in ('ver', 'command /c ver', 'cmd /c ver'):
  308.         
  309.         try:
  310.             pipe = popen(cmd)
  311.             info = pipe.read()
  312.             if pipe.close():
  313.                 raise os.error, 'command failed'
  314.         except os.error:
  315.             why = None
  316.             continue
  317.             continue
  318.             except IOError:
  319.                 why = None
  320.                 continue
  321.                 continue
  322.             else:
  323.                 break
  324.         return (system, release, version)
  325.         info = string.strip(info)
  326.         m = _ver_output.match(info)
  327.         if m:
  328.             (system, release, version) = m.groups()
  329.             if release[-1] == '.':
  330.                 release = release[:-1]
  331.             
  332.             if version[-1] == '.':
  333.                 version = version[:-1]
  334.             
  335.             version = _norm_version(version)
  336.         
  337.  
  338.     return (system, release, version)
  339.  
  340.  
  341. def _win32_getvalue(key, name, default = ''):
  342.     ''' Read a value for name from the registry key.
  343.  
  344.         In case this fails, default is returned.
  345.  
  346.     '''
  347.     RegQueryValueEx = RegQueryValueEx
  348.     import win32api
  349.     
  350.     try:
  351.         return RegQueryValueEx(key, name)
  352.     except:
  353.         return default
  354.  
  355.  
  356.  
  357. def win32_ver(release = '', version = '', csd = '', ptype = ''):
  358.     """ Get additional version information from the Windows Registry
  359.         and return a tuple (version,csd,ptype) referring to version
  360.         number, CSD level and OS type (multi/single
  361.         processor).
  362.  
  363.         As a hint: ptype returns 'Uniprocessor Free' on single
  364.         processor NT machines and 'Multiprocessor Free' on multi
  365.         processor machines. The 'Free' refers to the OS version being
  366.         free of debugging code. It could also state 'Checked' which
  367.         means the OS version uses debugging code, i.e. code that
  368.         checks arguments, ranges, etc. (Thomas Heller).
  369.  
  370.         Note: this function only works if Mark Hammond's win32
  371.         package is installed and obviously only runs on Win32
  372.         compatible platforms.
  373.  
  374.     """
  375.     
  376.     try:
  377.         import win32api
  378.     except ImportError:
  379.         return (release, version, csd, ptype)
  380.  
  381.     RegQueryValueEx = RegQueryValueEx
  382.     RegOpenKeyEx = RegOpenKeyEx
  383.     RegCloseKey = RegCloseKey
  384.     GetVersionEx = GetVersionEx
  385.     import win32api
  386.     HKEY_LOCAL_MACHINE = HKEY_LOCAL_MACHINE
  387.     VER_PLATFORM_WIN32_NT = VER_PLATFORM_WIN32_NT
  388.     VER_PLATFORM_WIN32_WINDOWS = VER_PLATFORM_WIN32_WINDOWS
  389.     import win32con
  390.     (maj, min, buildno, plat, csd) = GetVersionEx()
  391.     version = '%i.%i.%i' % (maj, min, buildno & 65535)
  392.     if csd[:13] == 'Service Pack ':
  393.         csd = 'SP' + csd[13:]
  394.     
  395.     if plat == VER_PLATFORM_WIN32_WINDOWS:
  396.         regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
  397.         if maj == 4:
  398.             if min == 0:
  399.                 release = '95'
  400.             elif min == 10:
  401.                 release = '98'
  402.             elif min == 90:
  403.                 release = 'Me'
  404.             else:
  405.                 release = 'postMe'
  406.         elif maj == 5:
  407.             release = '2000'
  408.         
  409.     elif plat == VER_PLATFORM_WIN32_NT:
  410.         regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
  411.         if maj <= 4:
  412.             release = 'NT'
  413.         elif maj == 5:
  414.             if min == 0:
  415.                 release = '2000'
  416.             elif min == 1:
  417.                 release = 'XP'
  418.             elif min == 2:
  419.                 release = '2003Server'
  420.             else:
  421.                 release = 'post2003'
  422.         
  423.     elif not release:
  424.         release = '%i.%i' % (maj, min)
  425.     
  426.     return (release, version, csd, ptype)
  427.     
  428.     try:
  429.         keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
  430.         RegQueryValueEx(keyCurVer, 'SystemRoot')
  431.     except:
  432.         return (release, version, csd, ptype)
  433.  
  434.     build = _win32_getvalue(keyCurVer, 'CurrentBuildNumber', ('', 1))[0]
  435.     ptype = _win32_getvalue(keyCurVer, 'CurrentType', (ptype, 1))[0]
  436.     version = _norm_version(version, build)
  437.     RegCloseKey(keyCurVer)
  438.     return (release, version, csd, ptype)
  439.  
  440.  
  441. def _mac_ver_lookup(selectors, default = None):
  442.     gestalt = gestalt
  443.     import gestalt
  444.     import MacOS as MacOS
  445.     l = []
  446.     append = l.append
  447.     for selector in selectors:
  448.         
  449.         try:
  450.             append(gestalt(selector))
  451.         continue
  452.         except (RuntimeError, MacOS.Error):
  453.             append(default)
  454.             continue
  455.         
  456.  
  457.     
  458.     return l
  459.  
  460.  
  461. def _bcd2str(bcd):
  462.     return hex(bcd)[2:]
  463.  
  464.  
  465. def mac_ver(release = '', versioninfo = ('', '', ''), machine = ''):
  466.     """ Get MacOS version information and return it as tuple (release,
  467.         versioninfo, machine) with versioninfo being a tuple (version,
  468.         dev_stage, non_release_version).
  469.  
  470.         Entries which cannot be determined are set to the paramter values
  471.         which default to ''. All tuple entries are strings.
  472.  
  473.         Thanks to Mark R. Levinson for mailing documentation links and
  474.         code examples for this function. Documentation for the
  475.         gestalt() API is available online at:
  476.  
  477.            http://www.rgaros.nl/gestalt/
  478.  
  479.     """
  480.     
  481.     try:
  482.         import gestalt
  483.         import MacOS
  484.     except ImportError:
  485.         return (release, versioninfo, machine)
  486.  
  487.     (sysv, sysu, sysa) = _mac_ver_lookup(('sysv', 'sysu', 'sysa'))
  488.     if sysv:
  489.         major = (sysv & 65280) >> 8
  490.         minor = (sysv & 240) >> 4
  491.         patch = sysv & 15
  492.         release = '%s.%i.%i' % (_bcd2str(major), minor, patch)
  493.     
  494.     if sysu:
  495.         major = int((sysu & 0xFF000000L) >> 24)
  496.         minor = (sysu & 15728640) >> 20
  497.         bugfix = (sysu & 983040) >> 16
  498.         stage = (sysu & 65280) >> 8
  499.         nonrel = sysu & 255
  500.         version = '%s.%i.%i' % (_bcd2str(major), minor, bugfix)
  501.         nonrel = _bcd2str(nonrel)
  502.         stage = {
  503.             32: 'development',
  504.             64: 'alpha',
  505.             96: 'beta',
  506.             128: 'final' }.get(stage, '')
  507.         versioninfo = (version, stage, nonrel)
  508.     
  509.     if sysa:
  510.         machine = {
  511.             1: '68k',
  512.             2: 'PowerPC' }.get(sysa, '')
  513.     
  514.     return (release, versioninfo, machine)
  515.  
  516.  
  517. def _java_getprop(name, default):
  518.     System = System
  519.     import java.lang
  520.     
  521.     try:
  522.         return System.getProperty(name)
  523.     except:
  524.         return default
  525.  
  526.  
  527.  
  528. def java_ver(release = '', vendor = '', vminfo = ('', '', ''), osinfo = ('', '', '')):
  529.     """ Version interface for Jython.
  530.  
  531.         Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
  532.         a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
  533.         tuple (os_name,os_version,os_arch).
  534.  
  535.         Values which cannot be determined are set to the defaults
  536.         given as parameters (which all default to '').
  537.  
  538.     """
  539.     
  540.     try:
  541.         import java.lang as java
  542.     except ImportError:
  543.         return (release, vendor, vminfo, osinfo)
  544.  
  545.     vendor = _java_getprop('java.vendor', vendor)
  546.     release = _java_getprop('java.version', release)
  547.     (vm_name, vm_release, vm_vendor) = vminfo
  548.     vm_name = _java_getprop('java.vm.name', vm_name)
  549.     vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
  550.     vm_release = _java_getprop('java.vm.version', vm_release)
  551.     vminfo = (vm_name, vm_release, vm_vendor)
  552.     (os_name, os_version, os_arch) = osinfo
  553.     os_arch = _java_getprop('java.os.arch', os_arch)
  554.     os_name = _java_getprop('java.os.name', os_name)
  555.     os_version = _java_getprop('java.os.version', os_version)
  556.     osinfo = (os_name, os_version, os_arch)
  557.     return (release, vendor, vminfo, osinfo)
  558.  
  559.  
  560. def system_alias(system, release, version):
  561.     ''' Returns (system,release,version) aliased to common
  562.         marketing names used for some systems.
  563.  
  564.         It also does some reordering of the information in some cases
  565.         where it would otherwise cause confusion.
  566.  
  567.     '''
  568.     if system == 'Rhapsody':
  569.         return ('MacOS X Server', system + release, version)
  570.     elif system == 'SunOS':
  571.         if release < '5':
  572.             return (system, release, version)
  573.         
  574.         l = string.split(release, '.')
  575.         if l:
  576.             
  577.             try:
  578.                 major = int(l[0])
  579.             except ValueError:
  580.                 pass
  581.  
  582.             major = major - 3
  583.             l[0] = str(major)
  584.             release = string.join(l, '.')
  585.         
  586.         if release < '6':
  587.             system = 'Solaris'
  588.         else:
  589.             system = 'Solaris'
  590.     elif system == 'IRIX64':
  591.         system = 'IRIX'
  592.         if version:
  593.             version = version + ' (64bit)'
  594.         else:
  595.             version = '64bit'
  596.     elif system in ('win32', 'win16'):
  597.         system = 'Windows'
  598.     
  599.     return (system, release, version)
  600.  
  601.  
  602. def _platform(*args):
  603.     ''' Helper to format the platform string in a filename
  604.         compatible format e.g. "system-version-machine".
  605.     '''
  606.     platform = string.join(map(string.strip, filter(len, args)), '-')
  607.     replace = string.replace
  608.     platform = replace(platform, ' ', '_')
  609.     platform = replace(platform, '/', '-')
  610.     platform = replace(platform, '\\', '-')
  611.     platform = replace(platform, ':', '-')
  612.     platform = replace(platform, ';', '-')
  613.     platform = replace(platform, '"', '-')
  614.     platform = replace(platform, '(', '-')
  615.     platform = replace(platform, ')', '-')
  616.     platform = replace(platform, 'unknown', '')
  617.     while None:
  618.         cleaned = replace(platform, '--', '-')
  619.         if cleaned == platform:
  620.             break
  621.         
  622.         platform = cleaned
  623.     while platform[-1] == '-':
  624.         platform = platform[:-1]
  625.     return platform
  626.  
  627.  
  628. def _node(default = ''):
  629.     ''' Helper to determine the node name of this machine.
  630.     '''
  631.     
  632.     try:
  633.         import socket as socket
  634.     except ImportError:
  635.         return default
  636.  
  637.     
  638.     try:
  639.         return socket.gethostname()
  640.     except socket.error:
  641.         return default
  642.  
  643.  
  644. if not hasattr(os.path, 'abspath'):
  645.     
  646.     def _abspath(path, isabs = os.path.isabs, join = os.path.join, getcwd = os.getcwd, normpath = os.path.normpath):
  647.         if not isabs(path):
  648.             path = join(getcwd(), path)
  649.         
  650.         return normpath(path)
  651.  
  652. else:
  653.     _abspath = os.path.abspath
  654.  
  655. def _follow_symlinks(filepath):
  656.     ''' In case filepath is a symlink, follow it until a
  657.         real file is reached.
  658.     '''
  659.     filepath = _abspath(filepath)
  660.     while os.path.islink(filepath):
  661.         filepath = os.path.normpath(os.path.join(filepath, os.readlink(filepath)))
  662.     return filepath
  663.  
  664.  
  665. def _syscmd_uname(option, default = ''):
  666.     """ Interface to the system's uname command.
  667.     """
  668.     if sys.platform in ('dos', 'win32', 'win16', 'os2'):
  669.         return default
  670.     
  671.     
  672.     try:
  673.         f = os.popen('uname %s 2> /dev/null' % option)
  674.     except (AttributeError, os.error):
  675.         return default
  676.  
  677.     output = string.strip(f.read())
  678.     rc = f.close()
  679.     if not output or rc:
  680.         return default
  681.     else:
  682.         return output
  683.  
  684.  
  685. def _syscmd_file(target, default = ''):
  686.     """ Interface to the system's file command.
  687.  
  688.         The function uses the -b option of the file command to have it
  689.         ommit the filename in its output and if possible the -L option
  690.         to have the command follow symlinks. It returns default in
  691.         case the command should fail.
  692.  
  693.     """
  694.     target = _follow_symlinks(target)
  695.     
  696.     try:
  697.         f = os.popen('file %s 2> /dev/null' % target)
  698.     except (AttributeError, os.error):
  699.         return default
  700.  
  701.     output = string.strip(f.read())
  702.     rc = f.close()
  703.     if not output or rc:
  704.         return default
  705.     else:
  706.         return output
  707.  
  708. _default_architecture = {
  709.     'win32': ('', 'WindowsPE'),
  710.     'win16': ('', 'Windows'),
  711.     'dos': ('', 'MSDOS') }
  712. _architecture_split = re.compile('[\\s,]').split
  713.  
  714. def architecture(executable = sys.executable, bits = '', linkage = ''):
  715.     ''' Queries the given executable (defaults to the Python interpreter
  716.         binary) for various architecture information.
  717.  
  718.         Returns a tuple (bits,linkage) which contains information about
  719.         the bit architecture and the linkage format used for the
  720.         executable. Both values are returned as strings.
  721.  
  722.         Values that cannot be determined are returned as given by the
  723.         parameter presets. If bits is given as \'\', the sizeof(pointer)
  724.         (or sizeof(long) on Python version < 1.5.2) is used as
  725.         indicator for the supported pointer size.
  726.  
  727.         The function relies on the system\'s "file" command to do the
  728.         actual work. This is available on most if not all Unix
  729.         platforms. On some non-Unix platforms where the "file" command
  730.         does not exist and the executable is set to the Python interpreter
  731.         binary defaults from _default_architecture are used.
  732.  
  733.     '''
  734.     if not bits:
  735.         import struct as struct
  736.         
  737.         try:
  738.             size = struct.calcsize('P')
  739.         except struct.error:
  740.             size = struct.calcsize('l')
  741.  
  742.         bits = str(size * 8) + 'bit'
  743.     
  744.     output = _syscmd_file(executable, '')
  745.     if not output and executable == sys.executable:
  746.         if _default_architecture.has_key(sys.platform):
  747.             (b, l) = _default_architecture[sys.platform]
  748.             if b:
  749.                 bits = b
  750.             
  751.             if l:
  752.                 linkage = l
  753.             
  754.         
  755.         return (bits, linkage)
  756.     
  757.     fileout = _architecture_split(output)[1:]
  758.     if 'executable' not in fileout:
  759.         return (bits, linkage)
  760.     
  761.     if '32-bit' in fileout:
  762.         bits = '32bit'
  763.     elif 'N32' in fileout:
  764.         bits = 'n32bit'
  765.     elif '64-bit' in fileout:
  766.         bits = '64bit'
  767.     
  768.     if 'ELF' in fileout:
  769.         linkage = 'ELF'
  770.     elif 'PE' in fileout:
  771.         if 'Windows' in fileout:
  772.             linkage = 'WindowsPE'
  773.         else:
  774.             linkage = 'PE'
  775.     elif 'COFF' in fileout:
  776.         linkage = 'COFF'
  777.     elif 'MS-DOS' in fileout:
  778.         linkage = 'MSDOS'
  779.     
  780.     return (bits, linkage)
  781.  
  782. _uname_cache = None
  783.  
  784. def uname():
  785.     """ Fairly portable uname interface. Returns a tuple
  786.         of strings (system,node,release,version,machine,processor)
  787.         identifying the underlying platform.
  788.  
  789.         Note that unlike the os.uname function this also returns
  790.         possible processor information as an additional tuple entry.
  791.  
  792.         Entries which cannot be determined are set to ''.
  793.  
  794.     """
  795.     global _uname_cache
  796.     if _uname_cache is not None:
  797.         return _uname_cache
  798.     
  799.     
  800.     try:
  801.         (system, node, release, version, machine) = os.uname()
  802.     except AttributeError:
  803.         system = sys.platform
  804.         release = ''
  805.         version = ''
  806.         node = _node()
  807.         machine = ''
  808.         processor = ''
  809.         use_syscmd_ver = 1
  810.         if system == 'win32':
  811.             (release, version, csd, ptype) = win32_ver()
  812.             if release and version:
  813.                 use_syscmd_ver = 0
  814.             
  815.         
  816.         if use_syscmd_ver:
  817.             (system, release, version) = _syscmd_ver(system)
  818.             if system == 'Microsoft Windows':
  819.                 system = 'Windows'
  820.             
  821.         
  822.         if system in ('win32', 'win16'):
  823.             if not version:
  824.                 if system == 'win32':
  825.                     version = '32bit'
  826.                 else:
  827.                     version = '16bit'
  828.             
  829.             system = 'Windows'
  830.         elif system[:4] == 'java':
  831.             (release, vendor, vminfo, osinfo) = java_ver()
  832.             system = 'Java'
  833.             version = string.join(vminfo, ', ')
  834.             if not version:
  835.                 version = vendor
  836.             
  837.         elif os.name == 'mac':
  838.             (version, stage, nonrel) = (release,)
  839.             machine = mac_ver()
  840.             system = 'MacOS'
  841.         
  842.     except:
  843.         system in ('win32', 'win16')
  844.  
  845.     if system == 'OpenVMS':
  846.         if not release or release == '0':
  847.             release = version
  848.             version = ''
  849.         
  850.         
  851.         try:
  852.             import vms_lib as vms_lib
  853.         except ImportError:
  854.             pass
  855.  
  856.         (csid, cpu_number) = vms_lib.getsyi('SYI$_CPU', 0)
  857.         if cpu_number >= 128:
  858.             processor = 'Alpha'
  859.         else:
  860.             processor = 'VAX'
  861.     else:
  862.         processor = _syscmd_uname('-p', '')
  863.     if system == 'unknown':
  864.         system = ''
  865.     
  866.     if node == 'unknown':
  867.         node = ''
  868.     
  869.     if release == 'unknown':
  870.         release = ''
  871.     
  872.     if version == 'unknown':
  873.         version = ''
  874.     
  875.     if machine == 'unknown':
  876.         machine = ''
  877.     
  878.     if processor == 'unknown':
  879.         processor = ''
  880.     
  881.     _uname_cache = (system, node, release, version, machine, processor)
  882.     return _uname_cache
  883.  
  884.  
  885. def system():
  886.     """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
  887.  
  888.         An empty string is returned if the value cannot be determined.
  889.  
  890.     """
  891.     return uname()[0]
  892.  
  893.  
  894. def node():
  895.     """ Returns the computer's network name (which may not be fully
  896.         qualified)
  897.  
  898.         An empty string is returned if the value cannot be determined.
  899.  
  900.     """
  901.     return uname()[1]
  902.  
  903.  
  904. def release():
  905.     """ Returns the system's release, e.g. '2.2.0' or 'NT'
  906.  
  907.         An empty string is returned if the value cannot be determined.
  908.  
  909.     """
  910.     return uname()[2]
  911.  
  912.  
  913. def version():
  914.     """ Returns the system's release version, e.g. '#3 on degas'
  915.  
  916.         An empty string is returned if the value cannot be determined.
  917.  
  918.     """
  919.     return uname()[3]
  920.  
  921.  
  922. def machine():
  923.     """ Returns the machine type, e.g. 'i386'
  924.  
  925.         An empty string is returned if the value cannot be determined.
  926.  
  927.     """
  928.     return uname()[4]
  929.  
  930.  
  931. def processor():
  932.     """ Returns the (true) processor name, e.g. 'amdk6'
  933.  
  934.         An empty string is returned if the value cannot be
  935.         determined. Note that many platforms do not provide this
  936.         information or simply return the same value as for machine(),
  937.         e.g.  NetBSD does this.
  938.  
  939.     """
  940.     return uname()[5]
  941.  
  942. _sys_version_parser = re.compile('([\\w.+]+)\\s*\\(#(\\d+),\\s*([\\w ]+),\\s*([\\w :]+)\\)\\s*\\[([^\\]]+)\\]?')
  943. _sys_version_cache = None
  944.  
  945. def _sys_version():
  946.     """ Returns a parsed version of Python's sys.version as tuple
  947.         (version, buildno, builddate, compiler) referring to the Python
  948.         version, build number, build date/time as string and the compiler
  949.         identification string.
  950.  
  951.         Note that unlike the Python sys.version, the returned value
  952.         for the Python version will always include the patchlevel (it
  953.         defaults to '.0').
  954.  
  955.     """
  956.     global _sys_version_cache
  957.     if _sys_version_cache is not None:
  958.         return _sys_version_cache
  959.     
  960.     (version, buildno, builddate, buildtime, compiler) = _sys_version_parser.match(sys.version).groups()
  961.     buildno = int(buildno)
  962.     builddate = builddate + ' ' + buildtime
  963.     l = string.split(version, '.')
  964.     if len(l) == 2:
  965.         l.append('0')
  966.         version = string.join(l, '.')
  967.     
  968.     _sys_version_cache = (version, buildno, builddate, compiler)
  969.     return _sys_version_cache
  970.  
  971.  
  972. def python_version():
  973.     """ Returns the Python version as string 'major.minor.patchlevel'
  974.  
  975.         Note that unlike the Python sys.version, the returned value
  976.         will always include the patchlevel (it defaults to 0).
  977.  
  978.     """
  979.     return _sys_version()[0]
  980.  
  981.  
  982. def python_version_tuple():
  983.     ''' Returns the Python version as tuple (major, minor, patchlevel)
  984.         of strings.
  985.  
  986.         Note that unlike the Python sys.version, the returned value
  987.         will always include the patchlevel (it defaults to 0).
  988.  
  989.     '''
  990.     return string.split(_sys_version()[0], '.')
  991.  
  992.  
  993. def python_build():
  994.     ''' Returns a tuple (buildno, builddate) stating the Python
  995.         build number and date as strings.
  996.  
  997.     '''
  998.     return _sys_version()[1:3]
  999.  
  1000.  
  1001. def python_compiler():
  1002.     ''' Returns a string identifying the compiler used for compiling
  1003.         Python.
  1004.  
  1005.     '''
  1006.     return _sys_version()[3]
  1007.  
  1008. _platform_cache = { }
  1009.  
  1010. def platform(aliased = 0, terse = 0):
  1011.     ''' Returns a single string identifying the underlying platform
  1012.         with as much useful information as possible (but no more :).
  1013.  
  1014.         The output is intended to be human readable rather than
  1015.         machine parseable. It may look different on different
  1016.         platforms and this is intended.
  1017.  
  1018.         If "aliased" is true, the function will use aliases for
  1019.         various platforms that report system names which differ from
  1020.         their common names, e.g. SunOS will be reported as
  1021.         Solaris. The system_alias() function is used to implement
  1022.         this.
  1023.  
  1024.         Setting terse to true causes the function to return only the
  1025.         absolute minimum information needed to identify the platform.
  1026.  
  1027.     '''
  1028.     result = _platform_cache.get((aliased, terse), None)
  1029.     if result is not None:
  1030.         return result
  1031.     
  1032.     (system, node, release, version, machine, processor) = uname()
  1033.     if machine == processor:
  1034.         processor = ''
  1035.     
  1036.     if aliased:
  1037.         (system, release, version) = system_alias(system, release, version)
  1038.     
  1039.     if system == 'Windows':
  1040.         (rel, vers, csd, ptype) = win32_ver(version)
  1041.         if terse:
  1042.             platform = _platform(system, release)
  1043.         else:
  1044.             platform = _platform(system, release, version, csd)
  1045.     elif system in ('Linux',):
  1046.         (distname, distversion, distid) = dist('')
  1047.         if distname and not terse:
  1048.             platform = _platform(system, release, machine, processor, 'with', distname, distversion, distid)
  1049.         else:
  1050.             (libcname, libcversion) = libc_ver(sys.executable)
  1051.             platform = _platform(system, release, machine, processor, 'with', libcname + libcversion)
  1052.     elif system == 'Java':
  1053.         (os_name, os_version, os_arch) = (r, v, vminfo)
  1054.         if terse:
  1055.             platform = _platform(system, release, version)
  1056.         else:
  1057.             platform = _platform(system, release, version, 'on', os_name, os_version, os_arch)
  1058.     elif system == 'MacOS':
  1059.         if terse:
  1060.             platform = _platform(system, release)
  1061.         else:
  1062.             platform = _platform(system, release, machine)
  1063.     elif terse:
  1064.         platform = _platform(system, release)
  1065.     else:
  1066.         (bits, linkage) = architecture(sys.executable)
  1067.         platform = _platform(system, release, machine, processor, bits, linkage)
  1068.     _platform_cache[(aliased, terse)] = platform
  1069.     return platform
  1070.  
  1071. if __name__ == '__main__':
  1072.     if not 'terse' in sys.argv:
  1073.         pass
  1074.     terse = '--terse' in sys.argv
  1075.     if 'nonaliased' not in sys.argv:
  1076.         pass
  1077.     aliased = '--nonaliased' not in sys.argv
  1078.     print platform(aliased, terse)
  1079.     sys.exit(0)
  1080.  
  1081.